home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / basic / qbredir.zip / QBREDIR.LST < prev    next >
File List  |  1992-03-01  |  37KB  |  501 lines

  1. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 1
  2. QBREDIR.ASM
  3.  
  4.       1
  5.       2                              ;                Quick Basic Redirected File Display
  6.       3                              ;
  7.       4                              ;
  8.       5                              ;    ----   A modified version of the original PD program REDVIEW.ASM   ----
  9.       6                              ;           by Alexandr Novy and Peter Horak of Prague, Czechoslovakia
  10.       7                              ;
  11.       8                              ;
  12.       9                              ;    ----   This Public Domain Adaptation for QuickBasic Written By:
  13.      10                              ;
  14.      11                              ;                       Peter R. Barnes
  15.      12                              ;                       Brentwood, TN
  16.      13                              ;                       March, 1992
  17.      14                              ;
  18.      15                              ;
  19.      16                              ;    ----   To assemble the object module with TASM, use the command:
  20.      17                              ;
  21.      18                              ;                   TASM QBREDIR   ;I don't have MASM,
  22.      19                              ;                                  ;but I'm sure the
  23.      20                              ;                                  ;syntax is the same
  24.      21                              ;
  25.      22                              ;
  26.      23                              ;    ----   To use in a QuickBasic program, compile your program
  27.      24                              ;           and link the module to your code, for example:
  28.      25                              ;
  29.      26                              ;                   BC /options YOURPROG;       ;any options you want
  30.      27                              ;
  31.      28                              ;                   LINK /linkoptions YOURPROG + QBREDIR;
  32.      29                              ;
  33.      30                              ;
  34.      31                              ;
  35.      32                              ;    ----   To call the routines in your program, use the following:
  36.      33                              ;
  37.      34                              ;                   CALL QFRedSet (FlagIntegerVariable%)
  38.      35                              ;
  39.      36                              ;                   CALL QFRedOff
  40.      37                              ;
  41.      38                              ;
  42.      39                              ;    --- IMPORTANT: READ THE QBREDIR.DOC FILE TO SEE HOW TO
  43.      40                              ;                   PROPERLY USE THESE ROUTINES!!  THE ROUTINES
  44.      41                              ;                   INSTALL A CUSTOM INTERRUPT HANDLER WHICH
  45.      42                              ;                   MUST BE TREATED WITH CARE!!
  46.      43                              ;
  47.      44                              ;    ----     NOTE: CANNOT BE USED IN THE QB ENVIRONMENT (SEE
  48.      45                              ;                   QBREDIR.DOC)
  49.      46                              ;
  50.      47                              ;
  51.      48                              ;    ----   I have  added some comments to help explain the code as
  52.      49                              ;           it applies to QuickBasic, just for general (and my own)
  53.      50                              ;           reference.  Some of the stuff is pretty elementary, so if
  54.      51                              ;           you are an assembly language wiz, just skip it; it's there
  55.      52                              ;           for the rest of us.
  56.      53                              ;
  57.      54                              ;
  58.      55                              ;********************************************************************
  59.      56                              ;********************************************************************
  60.      57                              ;
  61.      58                              ; Make our procedure names available to external programs
  62.      59                              ;
  63. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 2
  64. QBREDIR.ASM
  65.  
  66.      60                              public QFRedSet, QFRedOff
  67.      61                              ;
  68.      62                              ;
  69.      63                              ;********************************************************************
  70.      64                              ;
  71.      65                              ; All Basic modules are assembled using the Medium
  72.      66                              ; memory model, so we must add the proper assembler directives
  73.      67                              ;
  74.      68                              ;
  75.      69 0000                         .MODEL Medium, Basic               ;always, for QuickBasic
  76.      70                              ;
  77.      71 0000                         .CODE                              ;make the code segment our default
  78.      72                              ;
  79.      73                              ;
  80.      74                              ;
  81.      75                              ; We will let QBasic and TASM set the type of procedure, and we will
  82.      76                              ; declare the module using the TASM simplified format
  83.      77                              ;
  84.      78                              ;
  85.      79 0000                         QFRedSet proc  uses si di es ds
  86.      80       = 0002                                ARG flag:PTR = ARGLEN
  87.      81                              ;
  88.      82                              ;
  89.      83                              ; That tells TASM to add code for a Basic procedure call, save
  90.      84                              ; si,di,es,ds pointers, and that we are passing to the procedure a
  91.      85                              ; two-byte pointer to the INTEGER (notice that I capitalized that --
  92.      86                              ; three guesses why) variable /flag/, consisting of ARGLEN number of
  93.      87                              ; bytes -- the QuickBasic 'call' automatically pushes that address onto
  94.      88                              ; the stack and TASM calculates the correct offset to those stack
  95.      89                              ; bytes when it assembles the code. All parameter addresses passed by
  96.      90                              ; QuickBasic are near references (offset only, 1 word or 2 bytes)
  97.      91                              ; unless you use the keyword SEG for the passed variable, which tells
  98.      92                              ; QuickBasic to pass the address as a far reference (segment:offset,
  99.      93                              ; 2 words or 4 bytes).
  100.      94                              ;                            ---------
  101.      95                              ; TASM knows from our 'Basic' directive that the variable we pass will
  102.      96                              ; be a 2-byte address, and that Basic always makes far calls, leaving a full,
  103.      97                              ; 2-word return address as the last 4 bytes on the stack; the variable
  104.      98                              ; address, next on the stack, will be at [B(ase)P(ointer)+6] from the
  105.      99                              ; present BP value (+ because the stack grows downward in memory).
  106.     100                              ; That's also how TASM knows that we need a far return, not a near
  107.     101                              ; return, and also how many bytes to discard, after it pops that QB
  108.     102                              ; return address, to restore the stack after the procedure ends --
  109.     103                              ; i.e. 2 bytes for the variable near address...
  110.     104                              ;
  111.     105                              ;        push  bp                 ;TASM automatically
  112.     106                              ;        mov   bp,sp              ;adds the code to save the B(ase)
  113.     107                              ;                                 ;P(ointer) to the stack in the stack
  114.     108                              ;                                 ;segment, and set up a new stack
  115.     109                              ;                                 ;that starts at the end of the old
  116.     110                              ;                                 ;one pointed to by the current
  117.     111                              ;                                 ;S(tack)P(ointer) -- i.e.
  118.     112                                                                ;   New bp = Old bp + sp
  119.     113                              ;                                 ;Actually, our new stack will begin
  120.     114                              ;                                 ;at New bp + sp, but this will keep
  121.     115                              ;                                 ;us away from the old stack for
  122.     116                              ;                                 ;all values of sp, in case sp gets
  123.     117                              ;                                 ;set to a lower value -- we will
  124.     118                              ;                                 ;never get lower than the new bp.
  125. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 3
  126. QBREDIR.ASM
  127.  
  128.     119                              ;                                 ;Of course, we have to be careful
  129.     120                              ;                                 ;to preserve that sp value in our
  130.     121                              ;                                 ;code by always 'popping' the same
  131.     122                              ;                                 ;number of bytes that we 'push'
  132.     123                              ;                                 ;onto the stack.
  133.     124                              ;
  134.     125                              ;
  135.     126                              ;                                 ;This is the code that is added
  136.     127                              ;                                 ;by TASM when it sees the 'Basic'
  137.     128                              ;         push  si                ;and the 'uses' directives, so we
  138.     129                              ;         push  di                ;don't need the explicit statements.
  139.     130                              ;         push  es                ;The address of /flag/ is placed on
  140.     131                              ;         push  ds                ;the stack first, and ARGLEN tells
  141.     132                              ;                                 ;TASM how many bytes to discard, when
  142.     133                              ;                                 ;we return from the call, to get
  143.     134                              ;                                 ;back to the original stack before
  144.     135                              ;                                 ;the call.
  145.     136                              ;
  146.     137                              ;
  147.     138                              ;********************************************************************
  148.     139                              ;
  149.     140                              ;
  150.     141                              ;
  151.     142                              ; The first thing we do is grab and save the address of the QB variable
  152.     143                              ; that was passed to us, on the stack, by QuickBasic when it made the
  153.     144                              ; call; remember that TASM knows that [flag] means [BP+6]. In this
  154.     145                              ; call, we passed the 2-byte offset address of the variable in the
  155.     146                              ; ds data segment, so the 'word ptr [flag]' will have the 2-byte word
  156.     147                              ; for the offset moved into ax; then the 2-byte word for the ds data
  157.     148                              ; segment, whatever it is, will be stored. Both of those values are
  158.     149                              ; copied into /flagadr/ by the following 3 mov instructions:
  159.     150                              ;
  160.     151                              ;
  161.     152 0000  55 8B EC 56 57 06 1E +          mov   ax,word ptr [flag]  ;save the offset of passed
  162.     153       8B 46 06
  163.     154 000A  2E: A3 00EDr                    mov   cs:flagadr,ax       ;integer variable /flag/ in
  164.     155                              ;                                  ;memory location /flagadr/
  165.     156                              ;
  166.     157                              ;
  167.     158                              ; That saves the offset that we passed, now we save the data segment
  168.     159                              ; pointer that is in ds at the time of the call. Since QuickBasic
  169.     160                              ; only has one data segment for integer variables, ds will already be
  170.     161                              ; pointing to the segment containing our /flag/ variable.
  171.     162                              ;
  172.     163                              ; We could pass the segment pointer when we made the call from
  173.     164                              ; QuickBasic by preceding the variable name with the SEG keyword; in
  174.     165                              ; that situation, QuickBasic would push the full 4-byte address onto
  175.     166                              ; the stack. We could also use the CALLS statement to call this
  176.     167                              ; routine, instead of CALL, because that statement always passes the
  177.     168                              ; full address of parameters.  But neither of those actions are
  178.     169                              ; required, because QuickBasic only has one data segment
  179.     170                              ;
  180.     171                              ; The following mov instruction saves our data segment for DOS to
  181.     172                              ; use to find our variable when it executes the interrupt routine:
  182.     173                              ;
  183.     174                              ;
  184.     175 000E  2E: 8C 1E 00EFr                 mov   cs:flagadr+2,ds     ;save the segment pointer
  185.     176                              ;                                  ;of passed integer variable
  186.     177                              ;                                  ;/flag/ in second word
  187. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 4
  188. QBREDIR.ASM
  189.  
  190.     178                              ;                                  ;of /flagadr/ --
  191.     179                              ;                                  ;that's what DOS needs when
  192.     180                              ;                                  ;the interrupt is called
  193.     181                              ;
  194.     182                              ;
  195.     183                              ; Next step is flagcheck to prevent multiple calls to this routine
  196.     184                              ; if it has not been reset.  Without this check, a second call would
  197.     185                              ; save our new handler address as the original.
  198.     186                              ;
  199.     187                              ; Check to see if we have already installed the vector to the
  200.     188                              ; interrupt handler routine.  If we have, we don't want to do it
  201.     189                              ; again, because we will lose the original vector
  202.     190                              ;
  203.     191 0013  2E: A0 00ECr                    mov   al,cs:[IntSetFlag]  ;get flag to see if handler
  204.     192 0017  3C 00                           cmp   al,0                ;is already installed
  205.     193 0019  75 1F                           jne   EndSet              ;if set, we have installed
  206.     194                              ;                                  ;so go to exit
  207.     195                              ;
  208.     196 001B  B0 01                           mov   al, 1               ;else set the flag
  209.     197 001D  2E: A2 00ECr                    mov   cs:[IntSetFlag],al
  210.     198                              ;
  211.     199                              ;
  212.     200                              ;                                  ;pick up original vector contents
  213.     201                              ;
  214.     202 0021  B8 3521                         mov   ax,3521H            ;for interrupt 21H (MS-DOS Services
  215.     203 0024  CD 21                           int   21H                 ;Function Request handler)
  216.     204                              ;
  217.     205 0026  2E: 89 1E 00F1r                 mov   cs:Old21Offset,bx   ;save the original vector
  218.     206 002B  2E: 8C 06 00F3r                 mov   cs:Old21Segment,es  ;in our data area
  219.     207                              ;
  220.     208                              ;
  221.     209                              ;                                  ;a call to DOS services INT21H for
  222.     210                              ;                                  ;the SET INTERRUPT function 25xxH
  223.     211                              ;                                  ;requires ds:dx to be set to the
  224.     212                              ;                                  ;interrupt address, so the next two
  225.     213                              ;                                  ;statements set the ds segment
  226.     214                              ;                                  ;equal to the cs segment, where
  227.     215                              ;                                  ;our new handler procedure is
  228.     216                              ;                                  ;located
  229.     217                              ;
  230.     218                              ;
  231.     219 0030  0E                              push  cs                  ;push our code segment onto stack
  232.     220 0031  1F                              pop   ds                  ;pop it back off to set ds
  233.     221                              ;                                  ;i.e. sets ds=cs
  234.     222                              ;
  235.     223 0032  BA 0042r                        mov   dx,offset QDualDisp ;load offset of our Int 21 handler
  236.     224 0035  B8 2521                         mov   ax,02521H           ;and reset vector to point to
  237.     225 0038  CD 21                           int   21H                 ;our procedure
  238.     226                              ;
  239.     227                              ;
  240.     228                              ;         pop   ds                 ;restore registers and
  241.     229                              ;         pop   es                 ;return to our QB program
  242.     230                              ;         pop   di
  243.     231                              ;         pop   si                 ;NOTE--TASM automatically adds
  244.     232                              ;         pop   bp                 ;the code to restore registers
  245.     233                              ;
  246.     234 003A  1F 07 5F 5E 5D CA    + EndSet:  ret
  247.     235       0002
  248.     236                              ;
  249. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 5
  250. QBREDIR.ASM
  251.  
  252.     237                              ; actually, it's 'ret [ARGLEN]'    ;TASM automatically makes the
  253.     238                              ;                                  ;return discard the /flag/ address
  254.     239                              ;                                  ;bytes from the stack--the number
  255.     240                              ;                                  ;of bytes to discard was set by
  256.     241                              ;                                  ;the ARGLEN directive
  257.     242                              ;
  258.     243
  259.     244                              ;
  260.     245                              ;
  261.     246                              ;  Following is our new interrupt handler which is called by
  262.     247                              ;  MS-DOS whenever an Interrupt 21 MS-DOS Services Request
  263.     248                              ;  is detected.  The procedure first checks our enable flag
  264.     249                              ;  to determine if we want the dual output activated; the address of
  265.     250                              ;  this flag was passed by the QB program during the call to
  266.     251                              ;  the QFRedSet function.  If the flag is not set, we just skip our
  267.     252                              ;  handler and proceed to the regular interrupt 21 routine.
  268.     253                              ;
  269.     254                              ;  The handler then checks to see what type of service is being requested.
  270.     255                              ;  If it is a call to the DOS routines to output a character or a string
  271.     256                              ;  to STDOUT, the standard DOS output device, which is redirectible and
  272.     257                              ;  is always designated with file handle 1, then our procedure essentially
  273.     258                              ;  duplicates the routine by sending the output to STDERR, the standard
  274.     259                              ;  DOS error output device, which is always the display, file handle 2,
  275.     260                              ;  and whose output cannot be redirected.  Then the handler exits to the
  276.     261                              ;  normal Interrupt 21 procedure to let it process the original call.
  277.     262                              ;
  278.     263                              ;  Note that the routine is part of the QFRedSet procedure, but it is never
  279.     264                              ;  executed when that procedure is called by the QB program, because that
  280.     265                              ;  procedure ends at the 'ret' opcode at EndSet, above.
  281.     266                              ;
  282.     267                              QDualDisp:
  283.     268
  284.     269 0042  9C                              pushf                     ;save everything we can --
  285.     270 0043  50                              push  ax                  ;i.e. all registers and flags
  286.     271 0044  53                              push  bx
  287.     272 0045  51                              push  cx                  ;note that we save the flags
  288.     273 0046  52                              push  dx                  ;even though DOS did the same
  289.     274 0047  55                              push  bp                  ;thing when it called the
  290.     275 0048  56                              push  si                  ;interrupt routine
  291.     276 0049  57                              push  di
  292.     277
  293.     278
  294.     279 004A  53                              push  bx                  ;save entering register values
  295.     280 004B  1E                              push  ds
  296.     281 004C  2E: 8B 1E 00EDr                 mov   bx,cs:flagadr       ;get address of flag value passed
  297.     282 0051  2E: 8E 1E 00EFr                 mov   ds,cs:flagadr+2     ;from our QB program
  298.     283 0056  8A 07                           mov   al,ds:bx            ;get flag value into al
  299.     284 0058  1F                              pop   ds                  ;retrieve register values
  300.     285 0059  5B                              pop   bx
  301.     286
  302.     287 005A  0A C0                           or    al, al              ;see if value was zero
  303.     288 005C  74 57                           je    EndOur21            ;yes, don't do anything, go
  304.     289                                                                 ;to the regular interrupt 21 routine
  305.     290
  306.     291 005E  80 FC 02                        cmp   ah,02               ;was it a call to write character to STDOUT
  307.     292 0061  75 1C                           jne   Int9Chk             ;no, jump to next check
  308.     293
  309.     294 0063  1E                              push  ds                  ;yes, save entering data segment value
  310.     295 0064  0E                              push  cs                  ;set ds=cs
  311. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 6
  312. QBREDIR.ASM
  313.  
  314.     296 0065  1F                              pop   ds
  315.     297 0066  2E: 88 16 00F5r                 mov   cs:character,dl     ;save the character to write in character
  316.     298 006B  B4 40                           mov   ah,40h              ;set up for int 21 function 40h
  317.     299                                                                 ;to write character to output device
  318.     300 006D  BB 0002                         mov   bx,2                ;set file handle=2 for STDERR
  319.     301 0070  BA 00F5r                        mov   dx,OFFSET character ;get the pointer to the character
  320.     302 0073  B9 0001                         mov   cx,1                ;one character to be written
  321.     303 0076  9C                              pushf                     ;save current flag status
  322.     304 0077  2E: FF 1E 00F1r                 call  dword ptr cs:[Old21];use old interrupt routine to output
  323.     305                                                                 ;the character to the display,
  324.     306                                                                 ;it will pop the flags saved on stack
  325.     307                                                                 ;when it returns, because it ends with
  326.     308                                                                 ;iret, since it is an interrupt routine
  327.     309 007C  1F                              pop   ds                  ;retrieve our character
  328.     310 007D  EB 36                           jmp   short EndOur21      ;exit to old routine to write the character
  329.     311                                                                 ;to redirected output
  330.     312
  331.     313                              Int9Chk:
  332.     314 007F  80 FC 09                        cmp   ah,09               ;was it a call to write string to output
  333.     315 0082  75 1C                           jne   Int40Chk            ;no, go to next check
  334.     316
  335.     317                              Chrloop:
  336.     318 0084  8B F2                           mov   si,dx               ;yes, set index
  337.     319 0086  80 3C 24                        cmp   byte ptr ds:[si],'$';are we at the end of the string
  338.     320 0089  74 13                           je    End2109             ;yes, go to finish
  339.     321 008B  B4 40                           mov   ah,40h              ;no, set up for int 21 function 40h
  340.     322 008D  BB 0002                         mov   bx,2                ;output to STDERR
  341.     323 0090  B9 0001                         mov   cx,1
  342.     324 0093  52                              push  dx
  343.     325 0094  9C                              pushf
  344.     326 0095  2E: FF 1E 00F1r                 call  dword ptr cs:[Old21];write the character as above
  345.     327 009A  5A                              pop   dx
  346.     328 009B  42                              inc   dx                  ;bump index to next character
  347.     329 009C  EB E6                           jmp   short Chrloop       ;loop until done
  348.     330                              End2109:
  349.     331 009E  EB 15                           jmp   short EndOur21      ;exit to old routine to write the character
  350.     332                                                                 ;to redirected output
  351.     333
  352.     334                              Int40Chk:
  353.     335 00A0  80 FC 40                        cmp   ah,40h              ;was it a call to write to file or device
  354.     336 00A3  75 10                           jne   EndOur21            ;no, done, exit to regular int 21
  355.     337
  356.     338 00A5  83 FB 01                        cmp   bx,1                ;yes, then was it a call to STDOUT
  357.     339 00A8  75 0B                           jne   EndOur21            ;no, done, exit
  358.     340
  359.     341 00AA  1E                              push  ds                  ;yes, save character
  360.     342 00AB  BB 0002                         mov   bx,2                ;set file handle for STDERR
  361.     343 00AE  9C                              pushf
  362.     344 00AF  2E: FF 1E 00F1r                 call dword ptr cs:[Old21] ;use old interrupt routine to output
  363.     345 00B4  1F                              pop   ds                  ;retrieve character
  364.     346
  365.     347                              EndOur21:
  366.     348
  367.     349                                                                 ;retrieve registers
  368.     350 00B5  5F                              pop   di                  ;this resets registers
  369.     351 00B6  5E                              pop   si                  ;and flags to exactly
  370.     352 00B7  5D                              pop   bp                  ;where they were when we
  371.     353 00B8  5A                              pop   dx                  ;entered our custom handler
  372.     354 00B9  59                              pop   cx
  373. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 7
  374. QBREDIR.ASM
  375.  
  376.     355 00BA  5B                              pop   bx
  377.     356 00BB  58                              pop   ax
  378.     357 00BC  9D                              popf
  379.     358                              ;
  380.     359                              ;
  381.     360 00BD  2E: FF 2E 00F1r                 jmp dword ptr cs:[Old21]  ;go to regular int 21 routine
  382.     361                              ;
  383.     362                              ;
  384.     363                              ;
  385.     364                              ;
  386.     365 00C2                         QFRedSet  endp
  387.     366                              ;
  388.     367                              ;
  389.     368                              ;
  390.     369                              ;  The function QFRedOff is called by the QB program to
  391.     370                              ;  return the MS-DOS interrupt vector 21H to its' original state.
  392.     371                              ;  The function is used in the form:
  393.     372                              ;
  394.     373                              ;                   QFRedOff()
  395.     374                              ;
  396.     375                              ;
  397.     376 00C2                         QFRedOff  proc  uses si di es ds   ;Restore MS-DOS Services
  398.     377                              ;                                  ;interrupt vector 21H
  399.     378                              ;         push  bp                 ;to its' original state
  400.     379                              ;         mov   bp,sp
  401.     380                              ;         push  ds                 ;same code added as above
  402.     381                              ;         etc.
  403.     382                              ;
  404.     383                              ;
  405.     384                              ;  First we must check our IntSetFlag to see if the
  406.     385                              ;  vectors to our handler were installed; if not, we
  407.     386                              ;  do not want to reset them here, either
  408.     387                              ;
  409.     388                              ;
  410.     389 00C2  55 8B EC 56 57 06 1E +          mov   al,cs:[IntSetFlag]  ;Get our inhibit flag
  411.     390       2E: A0 00ECr
  412.     391 00CD  3C 01                           cmp   al,1                ;see if it is set
  413.     392 00CF  75 15                           jne   EndOff              ;no, go to exit
  414.     393                                                                 ;else, reset vector
  415.     394                              ;
  416.     395                              ;
  417.     396 00D1  2E: 8B 16 00F1r                 mov   dx,cs:Old21Offset   ;Set interrupt 21H MS-DOS
  418.     397 00D6  2E: 8E 1E 00F3r                 mov   ds,cs:Old21Segment  ;Services Request
  419.     398 00DB  B8 2521                         mov   ax,02521H           ;back to its' original vector
  420.     399 00DE  CD 21                           int   21H
  421.     400                              ;
  422.     401                              ;
  423.     402 00E0  B0 00                           mov   al, 0               ;reset the flag to enable
  424.     403 00E2  2E: A2 00ECr                    mov   cs:[IntSetFlag],al  ;the QFRedSet routine
  425.     404                              ;
  426.     405                              ;         pop   ds                 ;restore registers and
  427.     406                              ;         pop   bp                 ;return to QB program --
  428.     407                              ;         etc.                     ;same exit code added as above
  429.     408                              ;
  430.     409 00E6  1F 07 5F 5E 5D CB      EndOff:  ret
  431.     410                              ;
  432.     411 00EC                         QFRedOff endp
  433.     412                              ;
  434.     413                              ;
  435. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 8
  436. QBREDIR.ASM
  437.  
  438.     414                              ;
  439.     415 00EC  00                     IntSetFlag db  0                   ;this flag inhibits QFRedSet operation
  440.     416                              ;                                  ;after it has redirected vector
  441.     417                              ;                                  ;until QFRedOff resets it, and does
  442.     418                              ;                                  ;the same for QFRedOff if QFRedSet
  443.     419                              ;                                  ;has not redirected vector
  444.     420                              ;
  445.     421 00ED  0000 0000              flagadr  dw    0,0                 ;Long address of QB program's
  446.     422                              ;                                  ;display redirected output flag --
  447.     423                              ;                                  ;note that each '0' is actually 2 bytes
  448.     424                              ;
  449.     425                              Old21          Label Dword
  450.     426 00F1  ????                   Old21Offset    dw ?                ;Original contents of MS-DOS
  451.     427 00F3  ????                   Old21Segment   dw ?                ;Interrupt 21H vector
  452.     428
  453.     429                              ;
  454.     430                              ;
  455.     431 00F5  ??                     character      DB ?                ;storage for output character
  456.     432                              ;
  457.     433
  458.     434                                       end
  459. Turbo Assembler  Version 1.0        03-01-92 18:14:09         Page 9
  460. Symbol Table
  461.  
  462.  
  463. Symbol Name             Type   Value                       Cref  defined at #
  464.  
  465. ??DATE                  Text   "03-01-92"
  466. ??FILENAME              Text   "QBREDIR "
  467. ??TIME                  Text   "18:14:09"
  468. ??VERSION               Number 0100
  469. @CODE                   Text   QBREDIR_TEXT                #69  #71
  470. @CODESIZE               Text   1                           #69
  471. @CPU                    Text   0101H
  472. @CURSEG                 Text   QBREDIR_TEXT                #71
  473. @DATA                   Text   DGROUP                      #69
  474. @DATASIZE               Text   0                           #69
  475. @FILENAME               Text   QBREDIR
  476. @WORDSIZE               Text   2                           #71
  477. ARGLEN                  Number 0002                        #80
  478. CHARACTER               Byte   QBREDIR_TEXT:00F5           297  301  #431
  479. CHRLOOP                 Near   QBREDIR_TEXT:0084           #317  329
  480. END2109                 Near   QBREDIR_TEXT:009E           320  #330
  481. ENDOFF                  Near   QBREDIR_TEXT:00E6           392  #409
  482. ENDOUR21                Near   QBREDIR_TEXT:00B5           288  310  331  336  339  #347
  483. ENDSET                  Near   QBREDIR_TEXT:003A           193  #234
  484. FLAG                    Number [DGROUP:BP+0006]            #80  152
  485. FLAGADR                 Word   QBREDIR_TEXT:00ED           154  175  281  282  #421
  486. INT40CHK                Near   QBREDIR_TEXT:00A0           315  #334
  487. INT9CHK                 Near   QBREDIR_TEXT:007F           292  #313
  488. INTSETFLAG              Byte   QBREDIR_TEXT:00EC           191  197  389  403  #415
  489. OLD21                   Dword  QBREDIR_TEXT:00F1           304  326  344  360  #425
  490. OLD21OFFSET             Word   QBREDIR_TEXT:00F1           205  396  #426
  491. OLD21SEGMENT            Word   QBREDIR_TEXT:00F3           206  397  #427
  492. QDUALDISP               Near   QBREDIR_TEXT:0042           223  #267
  493. QFREDOFF                Far    QBREDIR_TEXT:00C2           60  #376
  494. QFREDSET                Far    QBREDIR_TEXT:0000           60  #79
  495.  
  496. Groups & Segments       Bit Size Align  Combine Class      Cref  defined at #
  497.  
  498. DGROUP                  Group                              #69  69
  499.   _DATA                 16  0000 Word   Public  DATA       #69
  500. QBREDIR_TEXT            16  00F6 Word   Public  CODE       #69  69  #71  71
  501.